function SocketHandler(url) {
  // 基于H5原生api
  this.ws = new WebSocket(url);
  // 定义一个信号发射塔，用于发送事件
  this.tower = document.createElement('div');
}

SocketHandler.prototype = {
  // 订阅频道
  channels : {},
  // 反应堆（用于收集和分发socket的响应）
  reactions : {},
  // 缓存监听事件
  events : [],
  // 获取当前时间
  nowTime : function() {
    return new Date().getTime();
  },
  // 打开socket连接
  open : function(heartbeatTimeout) {
    this.ws.onopen = function(){
      console.log('K线页面WebSocket连接已建立');
      var heartbeatSendInterval = heartbeatTimeout / 2;
      this.lastSubscribeTime = this.nowTime();
      this.pingIntervalId = setInterval(function(){
        var iv = this.nowTime() - this.lastSubscribeTime;
        // 超过一定时间自动与后台ping、pong  单位：秒
        if ((heartbeatSendInterval + iv) >= heartbeatTimeout) {
          this.send('ping');
        }
      }.bind(this), heartbeatSendInterval);
    }.bind(this);
  },

  // 创建自定义事件
  createEvent : function(event, detail){
    var evt = document.createEvent('CustomEvent');
    evt.initCustomEvent(event, false, false, detail);
    return evt;
  },

  // 打开socket连接
  connect: function(heartbeatTimeout) {
    console.log('K线页面开始连接WebSocket:', this.ws.url);
    this.open(heartbeatTimeout);
    this.message();
    this.close();
  },

  // 订阅消息 ch 为订阅的频道 id 为订阅唯一标识
  subscribe : function(ch, id, token) {
    console.log('K线页面尝试订阅频道:', ch, 'ID:', id);
    if(this.ws.readyState == 1) {
      console.log('WebSocket连接正常，准备发送订阅请求');
      var obj = {};
      if(ch) {
        obj.sub = ch;
        obj.id = id;
        if(token) obj.authorization = token;
        if(this.channels.hasOwnProperty(id)) {
          this.unsubscribe.apply(this, Object.values(this.channels[id]));
        }
        this.channels[id] = obj;
        this.reactions[ch] = this.createEvent(id);
        console.log('发送订阅请求对象:', obj);
        this.send(obj);
        console.log('订阅请求已发送');
      }
    } else {
      console.log('WebSocket连接未就绪，当前状态:', this.ws.readyState);
    }
  },

  // 监听订阅结果
  on : function(id, callback) {
    console.log('K线页面注册事件监听器:', id);
    var handler = function(e) {
      console.log('K线页面收到事件回调:', id, e.data);
      if(callback) callback(e.data, e);
    };
    this.tower.addEventListener(id, handler);
    var key = id + '_' + this.nowTime();
    this.events.push({key : key, handler: handler});
  },

  // 取消订阅
  unsubscribe : function(ch, id, token) {
    if(this.ws.readyState == 1) {
      var obj = {};
      if(ch) {
        obj.cancel = ch;
        obj.id = id;
        if(token) obj.authorization = token;
        if(this.channels.hasOwnProperty(id)) {
          delete this.channels[id];
          delete this.reactions[ch];
        }
        this.events = this.events.filter(function(v){
          if(v.key.indexOf(id) !== -1) {
            // 失效ID解除监听
            this.tower.removeEventListener(id, v.handler);
          }else{
            return v;
          }
        }.bind(this));
        this.send(obj);
      }
    }
  },

  send : function(data){
    if(typeof data === 'object') {
      data = JSON.stringify(data);
    }
    console.log('K线页面发送WebSocket消息:', data);
    this.ws.send(data);
  },

  message : function() {
    this.ws.onmessage = function(evt){
      var data = evt.data;
      console.log('K线页面收到WebSocket消息:', data);
      this.lastSubscribeTime = this.nowTime();
      if(data) {
        if(data !== 'pong') {
          try {
            data = JSON.parse(data);
            console.log('解析后的消息:', data);
          } catch(e) {
            console.error('消息解析失败:', e);
            return;
          }
        }
        
        // 处理订阅确认消息（包含result字段）
        if(typeof data === 'object' && data.hasOwnProperty('subbed') && data.hasOwnProperty('result')) {
          console.log('收到订阅确认消息，包含result字段:', data);
          try {
            var result = JSON.parse(data.result);
            console.log('解析result字段:', result);
            if(result.tick) {
              // 构造标准的频道数据格式
              var tickData = {
                ch: data.subbed,
                tick: typeof result.tick === 'string' ? JSON.parse(result.tick) : result.tick,
                ts: data.ts
              };
              console.log('构造的tickData:', tickData);
              var e = this.reactions[tickData.ch];
              if(e) {
                console.log('找到事件处理器，准备分发数据');
                e.data = tickData;
                this.tower.dispatchEvent(e);
              } else {
                console.log('未找到事件处理器:', tickData.ch);
              }
            }
          } catch(e) {
            console.error('处理订阅确认消息失败:', e);
          }
        }
        // 处理正常的频道数据
        else if(typeof data === 'object' && data.hasOwnProperty('ch')) {
          console.log('收到频道数据:', data.ch, data);
          var e = this.reactions[data.ch];
          if(e) {
            console.log('找到事件处理器，准备分发数据');
            e.data = data;
            this.tower.dispatchEvent(e);
          } else {
            console.log('未找到事件处理器:', data.ch);
          }
        } else {
          console.log('收到其他类型数据:', data);
        }
      }
    }.bind(this);
  },

  close : function(callback) {
    this.ws.onclose = function(evt){
      clearInterval(this.pingIntervalId);
      if(callback) callback(evt, this.ws);
    }.bind(this);
  }
};
